﻿namespace LizardChess
open System
open System.Windows.Forms
open System.Drawing
open System.Linq
open System.IO
open System.Reflection
open DGVPrinterHelper
module Dialogs =
    let ffrmAnal(isw, nm)=
        let this=new frmAnal()
        // OK
        let OK(e) =
            let proc = new System.Diagnostics.Process()
            proc.StartInfo.FileName <- Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),"LizardChessEng.exe")
            proc.StartInfo.Arguments <- this.colComboBox.Text.[0].ToString() + " " + this.varnComboBox.Text + (if this.allCheckBox.Checked then " ALL" else " END")
            proc.Start()|>ignore
            this.Close()
        this.OKButton.Click.Add(OK)
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "EngineSelVar.htm")
        this.helpButton.Click.Add(help)
        // colCombo
        let colCombo(e) =
            this.varnComboBox.Items.Clear()
            this.varnComboBox.Items.AddRange(if this.colComboBox.Text = "White" then Varn.wvarso() else Varn.bvarso())
            if this.varnComboBox.Items.Count>0 then this.varnComboBox.SelectedIndex <- 0
        this.colComboBox.SelectedIndexChanged.Add(colCombo)
        // load
        let load(e) =
            this.varnComboBox.Items.Clear()
            this.colComboBox.SelectedIndex <- if isw then 0 else 1
            this.varnComboBox.Items.AddRange(if isw then Varn.wvarso() else Varn.bvarso())
            this.varnComboBox.Text <- nm
        this.Load.Add(load)
        this

    let ffrmDelete() =
        let this=new frmDelete()
        // OK
        this.OKButton.Click.Add(fun _ -> this.Close())
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "VariationsDelete.htm")
        this.helpButton.Click.Add(help)
        // colCombo
        let colCombo(e) =
            this.varnComboBox.Items.Clear()
            this.varnComboBox.Items.AddRange(if this.colComboBox.Text = "White" then Varn.wvarso() else Varn.bvarso())
            if this.varnComboBox.Items.Count>0 then this.varnComboBox.SelectedIndex <- 0
        this.colComboBox.SelectedIndexChanged.Add(colCombo)
        // load
        let load(e) =
            this.varnComboBox.Items.Clear()
            this.varnComboBox.Items.AddRange(Varn.wvarso())
            if this.varnComboBox.Items.Count>0 then this.varnComboBox.SelectedIndex <- 0
        this.Load.Add(load)
        this

    let ffrmEngOpts() =
        let this=new frmEngOpts()
        // OK
        let OK(e) =
            let newset = [|this.engComboBox.SelectedItem.ToString();this.minNumericUpDown.Value.ToString();this.maxNumericUpDown.Value.ToString();(if this.logCheckBox.Checked then "T" else "F")|]
            Eng.saveSettings(newset)
            this.Close()
        this.OKButton.Click.Add(OK)
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "EngineOptions.htm")
        this.helpButton.Click.Add(help)
        // add
        let add(e) =
            if (this.engOpenFileDialog.ShowDialog() = DialogResult.OK) then
                File.Copy(this.engOpenFileDialog.FileName, Path.Combine(Eng.efold, Path.GetFileName(this.engOpenFileDialog.FileName)), true)
                this.engComboBox.Items.Clear()
                this.engComboBox.Items.AddRange(Eng.engineso());
                this.engComboBox.SelectedItem <- Path.GetFileNameWithoutExtension(this.engOpenFileDialog.FileName)
        this.addButton.Click.Add(add)
        // remove
        let remove(e) =
            let engexe = Path.Combine(Eng.efold, this.engComboBox.SelectedItem.ToString() + ".exe")
            File.Delete(engexe)
            this.engComboBox.Items.Clear()
            this.engComboBox.Items.AddRange(Eng.engineso())
            if (Eng.engineso().Count() > 0) then this.engComboBox.SelectedItem <- Eng.engineso().[0]
        this.removeButton.Click.Add(remove)
        // load
        let load(e) =
            let engopts = Eng.loadSettings()
            this.engComboBox.Items.Clear()
            this.engComboBox.Items.AddRange(Eng.engineso())
            this.engComboBox.SelectedItem <- engopts.engine
            this.minNumericUpDown.Value <- decimal(engopts.mindepth)
            this.maxNumericUpDown.Value <- decimal(engopts.maxdepth)
            this.logCheckBox.Checked <- engopts.log
        this.Load.Add(load)
        this

    let ffrmLoad() =
        let this=new frmLoad()
        // OK
        this.OKButton.Click.Add(fun _ -> this.Close())
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "VariationsLoad.htm")
        this.hlpButton.Click.Add(help)
        // colCombo
        let colCombo(e) =
            this.varnComboBox.Items.Clear()
            this.varnComboBox.Items.AddRange(if this.colComboBox.Text = "White" then Varn.wvarso() else Varn.bvarso())
            this.varnComboBox.Items.Add("<All>")|>ignore
            this.varnComboBox.SelectedIndex <- 0
        this.colComboBox.SelectedIndexChanged.Add(colCombo)
        // load
        let load(e) =
            this.varnComboBox.Items.Clear()
            this.varnComboBox.Items.AddRange(Varn.wvarso())
            this.varnComboBox.Items.Add("<All>")|>ignore
            this.varnComboBox.SelectedIndex <- 0
        this.Load.Add(load)
        this

    let ffrmNew() =
        let this=new frmNew()
        // OK
        this.OKButton.Click.Add(fun _ -> this.Close())
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "VariationsNew.htm")
        this.hlpButton.Click.Add(help)
        this

    let mutable m_MoveNameSelected = oMoveName.NullMove
    let ffrmPieceSelector(col) =
        let this=new frmPieceSelector()
        this.Colour <- col
        this.picWhiteQueen.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionQueen; this.Close())
        this.picBlackQueen.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionQueen; this.Close())
        this.picWhiteRook.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionRook; this.Close())
        this.picBlackRook.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionRook; this.Close())
        this.picWhiteBishop.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionBishop; this.Close())
        this.picBlackBishop.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionBishop; this.Close())
        this.picWhiteKnight.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionKnight; this.Close())
        this.picBlackKnight.Click.Add(fun _ -> m_MoveNameSelected <- oMoveName.PawnPromotionKnight; this.Close())
        this

    let ffrmRunTest(isw, nm, rnd) =
        let SQUARE_SIZE = 42
        let SQUARE_BRIGHTNESS = 48
        let BOARD_SQUARE_COLOUR_WHITE = Color.FromArgb(202,255,112)
        let BOARD_SQUARE_COLOUR_BLACK = Color.FromArgb(50, 205, 50)
        let BOARD_SQUARE_COLOUR_WHITE_BRIGHT = Color.FromArgb(Math.Min(169 + SQUARE_BRIGHTNESS, 255), Math.Min(147 + SQUARE_BRIGHTNESS, 255), Math.Min(83 + SQUARE_BRIGHTNESS, 255))
        let BOARD_SQUARE_COLOUR_BLACK_BRIGHT = Color.FromArgb(Math.Min(149 + SQUARE_BRIGHTNESS, 255), Math.Min(117 + SQUARE_BRIGHTNESS, 255), Math.Min(53 + SQUARE_BRIGHTNESS, 255))
        let m_squareTo = ref -1
        let CurrPosn = ref (Posn.st())
        let curTest = if rnd then Test.fromName nm isw else Test.fromNameLin nm isw
        let results = if rnd then Test.loadResults() else Test.loadResultsLin()
        let this=new frmRunTest()
        // BOARD
        // renderBoardColours
        let renderBoardColours(sqFrom,movesPossible) =
            for i in [0..2 ..6] do
                for j  in [0..2..6] do
                    this.m_picSquares.[i, j].BackColor <- BOARD_SQUARE_COLOUR_BLACK
                    this.m_picSquares.[i + 1, j + 1].BackColor <- BOARD_SQUARE_COLOUR_BLACK
                    this.m_picSquares.[i, j + 1].BackColor <- BOARD_SQUARE_COLOUR_WHITE
                    this.m_picSquares.[i + 1, j].BackColor <- BOARD_SQUARE_COLOUR_WHITE
            if (sqFrom <> -1) then
                for move in movesPossible do
                    let picTo = this.m_picSquares.[Ref.fi.[move.To], Ref.ri.[move.To]]
                    picTo.BackColor <- if picTo.BackColor = BOARD_SQUARE_COLOUR_WHITE then BOARD_SQUARE_COLOUR_WHITE_BRIGHT else BOARD_SQUARE_COLOUR_BLACK_BRIGHT
        // renderBoard
        let renderBoard(sqFrom,movesPossible) =
            renderBoardColours(sqFrom,movesPossible)
            for i = 0 to 63 do
                let sq = (!CurrPosn).Sqs.[i]
                if (sq = -1 || sq = sqFrom) then
                    this.m_picSquares.[Ref.fi.[i], Ref.ri.[i]].Image <- null
                else
                    this.m_picSquares.[Ref.fi.[i], Ref.ri.[i]].Image <- this.imgPieces.Images.[Posn.imageIndex(sq, !CurrPosn)]
                this.m_picSquares.[Ref.fi.[i], Ref.ri.[i]].BorderStyle <- BorderStyle.None
            if ((!CurrPosn).Mhst.Length > 0) then
                this.m_picSquares.[Ref.fi.[(!CurrPosn).Mhst.[0].From], Ref.ri.[(!CurrPosn).Mhst.[0].From]].BorderStyle <- BorderStyle.Fixed3D
                this.m_picSquares.[Ref.fi.[(!CurrPosn).Mhst.[0].To], Ref.ri.[(!CurrPosn).Mhst.[0].To]].BorderStyle <- BorderStyle.Fixed3D
            this.Refresh()
        // orientBoard
        let orientBoard() =
            for f = 0 to 7 do
                for r = 0 to 7 do
                    let picSquare = this.m_picSquares.[f, r]
                    if isw then
                        picSquare.Left <- f * SQUARE_SIZE + 1
                        picSquare.Top <- 7 * SQUARE_SIZE - r * SQUARE_SIZE + 1
                        for indCtrl = 0 to this.Controls.Count-1 do
                            let strName = this.Controls.[indCtrl].Name
                            if (strName.StartsWith("lblFile")) then
                                let iFileSize = Convert.ToInt32(strName.Substring(7, strName.Length - 7)) * SQUARE_SIZE
                                this.Controls.[indCtrl].Left <- iFileSize + 30
                            else if (strName.StartsWith("lblRank")) then
                                let iRankSize = Convert.ToInt32(strName.Substring(7, strName.Length - 7)) * SQUARE_SIZE
                                this.Controls.[indCtrl].Top <- 7 * SQUARE_SIZE - iRankSize + 16
                    else
                        picSquare.Left <- 7 * SQUARE_SIZE - f * SQUARE_SIZE + 1
                        picSquare.Top <- r * SQUARE_SIZE + 1
                        for indCtrl = 0 to this.Controls.Count-1 do
                            let strName = this.Controls.[indCtrl].Name
                            if (strName.StartsWith("lblFile")) then
                                let iFileSize = Convert.ToInt32(strName.Substring(7, strName.Length - 7)) * SQUARE_SIZE
                                this.Controls.[indCtrl].Left <- 7 * SQUARE_SIZE - iFileSize + 30
                            else if (strName.StartsWith("lblRank")) then
                                let iRankSize = System.Convert.ToInt32(strName.Substring(7, strName.Length - 7)) * SQUARE_SIZE
                                this.Controls.[indCtrl].Top <- iRankSize + 16

        // actions
        // close
        let close(e) =
            let correct = Convert.ToInt32(this.correctLabel.Text)
            let ans = Convert.ToInt32(this.ansLabel.Text)
            if (ans> curTest.Length-2 && ans>0) then
                let res = Test.createres(nm, isw, (100 * correct) / ans)
                if rnd then Test.saveRes(results, res) else Test.saveResLin(results, res)
            this.Close()
        this.closeButton.Click.Add(close)
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "TestRun.htm")
        this.helpButton.Click.Add(help)
        // runTest
        let runTest() =
            let tstnum0 = Convert.ToInt32(this.tstnumLabel.Text)
            let tstnum = if tstnum0 = curTest.Length-1 then 0 else tstnum0
            let correct = Convert.ToInt32(this.correctLabel.Text)
            let ans = Convert.ToInt32(this.ansLabel.Text)
            let tst = curTest.[tstnum]
            CurrPosn := Test.GetPosn(tst)
            this.ansLabel.Text <- (ans+1).ToString()
            this.correctLabel.Text <- (correct+1).ToString()
            this.tstnumLabel.Text <- (tstnum+1).ToString()
            renderBoard(-1,[])
        // mouseDown
        let mouseDown(s:obj,e:MouseEventArgs) =
            if not (e.Button <> MouseButtons.Left) then
                let picFrom = s:?>PictureBox
                let squareFrom = Convert.ToInt32(picFrom.Tag)
                let pcidFrom = (!CurrPosn).Sqs.[squareFrom]
                let pieceFrom = if pcidFrom= -1 then Piece.blank else (!CurrPosn).Pcs.[pcidFrom] 
                if (pcidFrom <> -1 && pieceFrom.pcIsWhite = (!CurrPosn).IsWhite) then
                    picFrom.Image <- null
                    picFrom.Refresh()
                    this.m_curPieceCursor <- this.m_acurPieceCursors.[Posn.imageIndex(pcidFrom, !CurrPosn)]
                    this.pnlEdging.Cursor <- this.m_curPieceCursor
                    // Mark possible moves
                    m_squareTo := -1
                    let movesPossible = Posn.GenerateLegalMoves(pcidFrom, !CurrPosn)
                    renderBoardColours(squareFrom,movesPossible)
                    this.pnlEdging.Refresh()
                    if (picFrom.DoDragDrop(pieceFrom, DragDropEffects.Move) = DragDropEffects.Move) then
                        let blnMoveMade = ref false
                        let pcidTo = (!CurrPosn).Sqs.[!m_squareTo]
                        if (pcidTo = -1 || (!CurrPosn).Pcs.[pcidTo].pcIsWhite <> (!CurrPosn).IsWhite) then
                            let ml1 = movesPossible |> List.filter (fun m -> m.To = !m_squareTo)
                            if ml1.Length>0 then
                                let move =
                                    if ml1.Length>1 then
                                        let formPieceSelector = ffrmPieceSelector(pieceFrom.pcIsWhite)
                                        formPieceSelector.ShowDialog(this)|>ignore
                                        ml1|>List.filter(fun m -> m.mvName = m_MoveNameSelected)|>List.head
                                    else ml1.[0]
                                CurrPosn := Posn.DoMove(move, !CurrPosn)
                                blnMoveMade := true
                                renderBoard(-1,[])
                                let dmv = (!CurrPosn).Mhst.[0].PGN
                                let tstnum = Convert.ToInt32(this.tstnumLabel.Text)-1
                                let tstmv = curTest.[tstnum].mv.PGN
                                if (dmv = tstmv) then
                                    this.msgLabel.Text <- dmv + " is correct."
                                    this.failpictureBox.Visible <- false
                                    this.succpictureBox.Visible <- true
                                    runTest()
                                else
                                    this.msgLabel.Text <- dmv + " is WRONG!"
                                    this.succpictureBox.Visible <- false
                                    this.failpictureBox.Visible <- true
                                    let tstnum = Convert.ToInt32(this.tstnumLabel.Text)-1
                                    this.tstnumLabel.Text <- tstnum.ToString()
                                    let correct = Convert.ToInt32(this.correctLabel.Text)-1
                                    this.correctLabel.Text <- correct.ToString()
                                    runTest()

                        if (not !blnMoveMade) then
                            this.m_picSquares.[Ref.fi.[squareFrom], Ref.ri.[squareFrom]].Image <- this.imgPieces.Images.[Posn.imageIndex(pcidFrom, !CurrPosn)]
                            renderBoardColours(-1,[])
                    else
                        this.m_picSquares.[Ref.fi.[squareFrom], Ref.ri.[squareFrom]].Image <- this.imgPieces.Images.[Posn.imageIndex(pcidFrom, !CurrPosn)]
                        renderBoardColours(-1,[])
                    this.pnlEdging.Cursor <- Cursors.Default
        // mouseUp
        let mouseUp(e) = ()
        // dragOver
        let dragOver(e:DragEventArgs) = e.Effect <- DragDropEffects.Move
        // dragDrop
        let dragDrop(pb:PictureBox,e) = m_squareTo := Convert.ToInt32(pb.Tag)
        // giveFeedback
        let giveFeedback(e:GiveFeedbackEventArgs) =
            if (e.UseDefaultCursors <> false) then e.UseDefaultCursors <- false
            if (this.pnlEdging.Cursor <> this.Cursor) then this.pnlEdging.Cursor <- this.m_curPieceCursor
        // createBoard
        let createBoard() =
            for r = 0 to 7 do
                let lblRank = new Label()
                lblRank.BackColor <- Color.Transparent
                lblRank.ForeColor <- BOARD_SQUARE_COLOUR_BLACK
                lblRank.Font <- new Font("Arial", 12.0F, FontStyle.Bold, GraphicsUnit.Point, byte(0))
                lblRank.Name <- "lblRank" + r.ToString()
                lblRank.Size <- new Size(SQUARE_SIZE / 2, SQUARE_SIZE)
                lblRank.Text <- (r + 1).ToString()
                lblRank.TextAlign <- ContentAlignment.MiddleCenter
                lblRank.Left <- 0
                lblRank.Top <- (8 - 1) * SQUARE_SIZE - r * SQUARE_SIZE + 16
                this.Controls.Add(lblRank)
            this.m_picSquares <- Array2D.create 8 8 (new PictureBox())
            for f = 0 to 7 do
                let lblFile = new Label()
                lblFile.BackColor <- Color.Transparent
                lblFile.ForeColor <- BOARD_SQUARE_COLOUR_BLACK
                lblFile.Font <- new Font("Arial", 12.0F, FontStyle.Bold, GraphicsUnit.Point, byte(0))
                lblFile.Name <- "lblFile" + f.ToString()
                lblFile.Size <- new Size(SQUARE_SIZE, SQUARE_SIZE / 2)
                lblFile.Text <- Ref.fs.[f]
                lblFile.TextAlign <- ContentAlignment.MiddleCenter
                lblFile.Left <- f * SQUARE_SIZE + 30
                lblFile.Top <- 8 * SQUARE_SIZE + 24
                this.Controls.Add(lblFile)
            for f = 0 to 7 do
                for r = 0 to 7 do
                    let picSquare = new PictureBox()
                    picSquare.Name <- "picSquare" + f.ToString() + r.ToString()
                    picSquare.Size <- new Size(SQUARE_SIZE, SQUARE_SIZE)
                    picSquare.SizeMode <- PictureBoxSizeMode.CenterImage
                    picSquare.Tag <- r * 8 + f
                    picSquare.MouseDown.Add(fun e -> mouseDown(picSquare,e))
                    picSquare.MouseUp.Add(mouseUp)
                    picSquare.DragDrop.Add(fun e -> dragDrop(picSquare,e))
                    picSquare.DragOver.Add(dragOver)
                    picSquare.GiveFeedback.Add(giveFeedback)
                    picSquare.AllowDrop <- true
                    this.pnlEdging.Controls.Add(picSquare)
                    this.m_picSquares.[f, r] <- picSquare
        // load
        let load(e) =
            this.Text <- if rnd then "Run Random Tests for Variation: " + nm else "Run Linear Tests for Variation: " + nm
            this.tstnumLabel.Text <- "0"
            this.numLabel.Text <- "of " + curTest.Length.ToString()
            this.pnlEdging.Visible <- false
            this.correctLabel.Text <- "-1"
            this.ansLabel.Text <- "-1"
            this.LoadCursors()
            createBoard()
            orientBoard()
            renderBoard(-1,[])
            this.pnlEdging.Visible <- true
            runTest()
        this.Load.Add(load)
        this

    let ffrmSaveAs() =
        let this=new frmSaveAs()
        // OK
        this.OKButton.Click.Add(fun _ -> this.Close())
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "VariationsSaveAS.htm")
        this.helpButton.Click.Add(help)
        this

    let ffrmTest(isw, nm, rnd)=
        let this=new frmTest()
        // OK
        this.OKButton.Click.Add(fun _ -> this.Close())
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "TestSelect.htm")
        this.helpButton.Click.Add(help)
        // colCombo
        let colCombo(e) =
            this.varnComboBox.Items.Clear()
            this.varnComboBox.Items.AddRange(if this.colComboBox.Text = "White" then Varn.wvarso() else Varn.bvarso())
            if rnd then this.varnComboBox.Items.Add("<All>")|>ignore
            if this.varnComboBox.Items.Count>0 then this.varnComboBox.SelectedIndex <- 0
        this.colComboBox.SelectedIndexChanged.Add(colCombo)
        // load
        let load(e) =
            this.varnComboBox.Items.Clear()
            this.Text <- if rnd then this.Text + " - Random" else this.Text + " - Linear"
            this.colComboBox.SelectedIndex <- if isw then 0 else 1
            this.varnComboBox.Items.AddRange(if isw then Varn.wvarso() else Varn.bvarso())
            if rnd then this.varnComboBox.Items.Add("<All>")|>ignore
            this.varnComboBox.Text <- nm
        this.Load.Add(load)
        this

    let ffrmTestOpts()=
        let this=new frmTestOpts()
        // OK
        let OK(e) =
            let newset = [|this.numNumericUpDown.Value.ToString(); this.skipNumericUpDown.Value.ToString()|]
            let newsetlin = [|this.linnumNumericUpDown.Value.ToString(); this.linskipNumericUpDown.Value.ToString()|]
            Test.saveSettings(newset)
            Test.saveSettingsLin(newsetlin)
            this.Close()
        this.OKButton.Click.Add(OK)
        // cancel
        this.CancButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "TestOptions.htm")
        this.helpButton.Click.Add(help)
        // load
        let load(e) =
            let testopts = Test.loadSettings()
            let testoptslin = Test.loadSettingsLin()
            this.numNumericUpDown.Value <- decimal(testopts.num)
            this.skipNumericUpDown.Value <- decimal(testopts.skip)
            this.linnumNumericUpDown.Value <- decimal(testoptslin.numlin)
            this.linskipNumericUpDown.Value <- decimal(testoptslin.skiplin)
        this.Load.Add(load)
        this

    let ffrmTestRes(rnd)=
        let this=new frmTestRes()
        // close
        this.closeButton.Click.Add(fun _ -> this.Close())
        // help
        let help(e) = Help.ShowHelp(this, Path.Combine(Application.StartupPath, "LizardChess.chm"), HelpNavigator.Topic, "TestResults.htm")
        this.helpButton.Click.Add(help)
        // load
        let load(e) =
            let getCol(scr) =
                if (scr = "-") then Color.DarkBlue
                elif (scr.Length = 3||(scr.Length=2 && scr.StartsWith("9"))) then Color.Green
                else Color.Red
            let results = if rnd then Test.getallres() else Test.getallreslin()
            this.Text <- if rnd then this.Text + " - Random" else this.Text + " - Linear"
            for res in results do
                let row = new DataGridViewRow()
                for item in res do
                    row.Cells.Add(new DataGridViewTextBoxCell(Value = item))|>ignore
                this.resDGV.Rows.Add(row)|>ignore
                for i = 0 to 3 do
                    this.resDGV.Rows.[this.resDGV.RowCount - 1].Cells.[i].Style.ForeColor <- getCol(res.[3])
            this.resDGV.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells)
            this.resDGV.Refresh()
        this.Load.Add(load)
        // resDgv
        let resDgv(e:DataGridViewCellEventArgs) =
            this.Cursor <- Cursors.WaitCursor
            this.Refresh()
            let rw = e.RowIndex
            let results = if rnd then Test.getallres() else Test.getallreslin()
            let res = results.[rw]
            let isw = (res.[0] = "White")
            let nm = res.[1]
            let formRunTest = ffrmRunTest(isw, nm, rnd)
            formRunTest.ShowDialog(this)|>ignore
            this.Cursor <- Cursors.Default
            this.resDGV.Rows.Clear()
            load(e)
        this.resDGV.CellDoubleClick.Add(resDgv)
        this
